local CountDown = require(SCRIPTS_DIR .. ".uikits.CountDown");
local Click = require(SCRIPTS_DIR .. ".uikits.Click");
local ClipWidget = require(SCRIPTS_DIR .. ".uikits.ClipWidget");
local RadioButton = require(SCRIPTS_DIR .. ".uikits.RadioButton");
local PageViewMark = require(SCRIPTS_DIR .. ".uikits.PageViewMark");
local ListView = require(SCRIPTS_DIR .. ".uikits.ListView");
local ScrollView = require(SCRIPTS_DIR .. ".uikits.ScrollView");
local PageView = require(SCRIPTS_DIR .. ".uikits.PageView");
local manager = ccs.ArmatureDataManager:getInstance();
local BaseWnd = class("BaseWnd",function()
	local node = display.newNode();
	node:setNodeEventEnabled(true);
	return node;
end)

function BaseWnd:ctor()
	mgrs.log:printDebug("%s:ctor()",self.__cname);
	self.wndData = nil;
	self.ui = nil;
	self.prefab = nil;
    self.listeners = {};
    self.schedulerCbks = {};--��ʱ���Ļٵ����� �ڴ��ڹر�ʱҪ����
end

--[[
	������������,��Ҫ�����������ٴ򿪽������Ӵ�����ʵ��
	@param {function}handler	
]]
function BaseWnd:reqData(handler)
	handler(true);
end
--[[
	��ȡ������������,Ĭ�Ͼ���
	@returns {{rx: number, ry: number, ox: number, oy: number}}	
]]
function BaseWnd:getRelativePosition()
	return {rx = 0.5; ry = 0.5; ox = mgrs.wnd.visibleRect.center.x; oy = mgrs.wnd.visibleRect.center.y;	};
end

--[[
	��ȡ�������ڵĲ㣬Ĭ����Window��
	@returns {int} enums.Layer
]]
function BaseWnd:getLayer()
	return enums.Layer.Window;
end

--[[
	��ȡԤ�ȼ��صĶ���
    Armature={},
    Png={},
    Plist={},
    Spine={}
]]
function BaseWnd:getPreloadResList()
	return {};
end

--[[
	��ȡ��������  0 - ������  ��0 - ��ͬ���ͻ���
]]
function BaseWnd:getExclusiveType()
	return 0;
end

--[[
	���������Լ��ر�ʱ�Ƿ񲥷���Ч
]]
function BaseWnd:isOpenCloseSoundEnabled()
	return false;
end


function BaseWnd:openWnd()
    local wndName = self.wndData.name;
    mgrs.log:printDebug("%s WndOpen",wndName);
    local ui = cc.uiloader:load(mgrs.res:getWndPath(wndName));
    local relativePos = self:getRelativePosition();
    ui:ignoreAnchorPointForPosition(false);
    ui:setAnchorPoint(cc.p(relativePos.rx,relativePos.ry));
    ui:setPosition(cc.p(relativePos.ox,relativePos.oy));
    self:setTouchEnabled(true);
	self:addChild(ui);
    self.ui = ui;
	self:dispatchEvent({name = enums.Event.WndOpen, data = self});
    if self:getExclusiveType() ~= 0 then
        mgrs.log:printNotice("openwnd %s",self.__cname);
		self:addEventListener(enums.Event.WndOpen,handler(self,self.wndOpenCbk));
	end
    self.prefab = self:widget("prefab");
    if self.prefab then
        self.prefab:retain();
        self.prefab:removeFromParent();
    end
    self:scheduleUpdate();
    self:addNodeEventListener(cc.NODE_ENTER_FRAME_EVENT,function(dt)
        self:unscheduleUpdate();
        self:dispatchEvent({name=enums.Event.PurgeCacheData});
        local preLoadResList = self:getPreloadResList();
        --preload plist
        local plist = preLoadResList.Plist;
        if plist and table.nums(plist)then
            for key, var in pairs(plist) do
                local path = mgrs.res:getPlistPath(var);
                display.addSpriteFrames(path .. "/" .. var .. ".plist",path .. "/" .. var .. ".png");
            end
        end
        --preload png and arm spine
        local png = preLoadResList.Png or {};
        local arm = preLoadResList.Armature or {};
        local spi = preLoadResList.Spine or {};

        local pngCount = table.nums(png);
        local armCount = table.nums(arm);
        local spiCount = table.nums(spi);
        local resCount = pngCount + armCount + spiCount;
        if resCount == 0 then
            self:onOpen();
            return;
        end
        local handle = nil;
        handle = self:addEventListener(enums.Event.LoadingAdd,function(e)
            local curPencent = e.data;
            mgrs.log:printNotice("wnd = %s,curPencent = %s",self.__cname,curPencent);
            if curPencent >= 1.0 or curPencent == -1 then
                --mgrs.log:printDebug("cache = %s",cc.Director:getInstance():getTextureCache():getCachedTextureInfo());
                mgrs.log:printNotice("openwnd = %s",self.__cname);
                self:removeEventListener(handle);
                self:onOpen();
            end
        end)

        local pngFinCount = 0;
        local armFinCount = 0;
        --load png
        local pngLoadCbk = function(texture)
            pngFinCount = pngFinCount + 1;
            mgrs.log:printDebug("pngFinCount = %s,hasFinCount = %s,precent = %s",pngFinCount,pngFinCount + armFinCount,(pngFinCount + armFinCount)/resCount);
            self:dispatchEvent({name = enums.Event.LoadingAdd, data = (pngFinCount + armFinCount)/resCount});
        end
        if pngCount ~= 0 then
            for key, var in pairs(png) do
                local path = mgrs.res:getPngPath(var);
                display.addImageAsync(path,pngLoadCbk);
            end
        end
        --load arm and spine
        local armLoadCbk = function(percent)
            armFinCount = percent * (armCount + spiCount);
            mgrs.log:printDebug("armFinCount = %s,hasFinCount = %s,precent = %s",percent,pngFinCount + armFinCount,(pngFinCount + armFinCount)/resCount);
            self:dispatchEvent({name = enums.Event.LoadingAdd, data = (pngFinCount + armFinCount)/resCount});
        end;

        if armCount ~= 0 then
            for key, var in pairs(arm) do
                local path = mgrs.res:getArmPath(var);
                manager:addArmatureFileInfoAsync(path .. "/" .. var .. ".ExportJson", armLoadCbk);
            end
        end
        if spiCount ~= 0 then
            for key, var in pairs(spi) do
                local path = mgrs.res:getSpinePath(var);
                manager:addArmatureFileInfoAsync(path .. "/" .. var .. ".png", path .. "/" .. var .. ".plist", path .. "/" .. var .. ".xml", armLoadCbk);
            end
        end
     end);
end


function BaseWnd:wndOpenCbk(d)
    mgrs.log:printDebug("wndOpenCbk %s",d.data.__cname);
	if(self:getExclusiveType() == d.data:getExclusiveType()) then
		self:close();
	end
end


function BaseWnd:addEventListener(eventName,cbkFunc,tag)
    local handle = mgrs.event:addEventListener(eventName,cbkFunc,tag);
    table.insert(self.listeners,handle);
    return handle;
end

function BaseWnd:dispatchEvent(eventName)
    if type(eventName) ~= "table" then
        eventName = {name = eventName};
    end
    mgrs.event:dispatchEvent(eventName)
end

function BaseWnd:removeAllEventListeners()
    for k,v in ipairs(self.listeners) do
        mgrs.event:removeEventListener(v);
    end
    self.listeners = {};
end

function BaseWnd:removeEventListener(handle)
    for key, var in pairs(self.listeners) do
        if var == handle then
            table.remove(self.listeners,key);
            mgrs.event:removeEventListener(handle);
            break;
        end
    end
end


function BaseWnd:dumpAllEventListeners()
    mgrs.event:dumpAllEventListeners();
end

function BaseWnd:onCleanup()
    mgrs.log:printDebug("BaseWnd:onCleanup");
    self:removeAllEventListeners();
	self.listeners = {};
    if self.prefab then
		self.prefab:release();
        self.prefab = nil;
    end
    self = nil;
end

function BaseWnd:close()
    mgrs.log:printDebug("BaseWnd:close  %s",self.wndData.name);
    self.wndData.wnd = nil;
    self.wndData.param = nil;
	self:onClose();
    self:removeAllSchedulerCbk();
    self:dispatchEvent({name = enums.Event.WndClose, data = self.wndData});
    self:removeResList();
    self:removeFromParent();
end

function BaseWnd:addSchedulerCbk(cbk,kind)
    kind = kind or enums.Scheduler.PerSecond;
    if kind == enums.Scheduler.PerSecond then
        mgrs.scheduler:addIntervalCbk(cbk);
    elseif kind == enums.Scheduler.Frame then
        mgrs.scheduler:addFrameCbk(cbk);
    end
    table.insert(self.schedulerCbks,cbk);
end

function BaseWnd:removeAllSchedulerCbk()
    mgrs.scheduler:delCbk(self.schedulerCbks);
end

function BaseWnd:removeResList()
    local preLoadResList = self:getPreloadResList();
    if preLoadResList.Armature and table.nums(preLoadResList.Armature) then
        for key, var in pairs(preLoadResList.Armature) do
            local path = mgrs.res:getArmPath(var);
            manager:removeArmatureFileInfo(path .. "/" .. var .. ".ExportJson");
        end
    end

    if preLoadResList.Spine and table.nums(preLoadResList.Spine) then
        for key, var in pairs(preLoadResList.Spine) do
            local path = mgrs.res:getSpinePath(var);
            manager:removeArmatureFileInfo(path .. "/" .. var .. ".xml");
        end
    end
end

function BaseWnd:widget(path,node)
	node = node or self.ui;
    local pas = string.split(path, ".");
    local find = node;
    if #pas == 1 then
        return cc.uiloader:seekNodeByPath(node,path);
    else
        for key, var in pairs(pas) do
           find = cc.uiloader:seekNodeByPath(find,var);
        end
    end
    return find;
end

function BaseWnd:createCountDown(node)
	return CountDown.new(node);
end

function BaseWnd:createClick(args)
	return Click.new(args);
end

function BaseWnd:createClipWidget(args)
    return ClipWidget.new(args);
end

function BaseWnd:createRadioButton(args)
    return RadioButton.new(args);
end

function BaseWnd:createPageViewMark(args)
    return PageViewMark.new(args);
end

function BaseWnd:createListView(args)
    if type(args) ~= "table" then
        return ListView.new({listView = args});
    end
    return ListView.new(args);
end

function BaseWnd:createScrollView(args)
    if type(args) ~= "table" then
        return ScrollView.new({sv = args});
    end
    return ScrollView.new(args);
end

function BaseWnd:createPageView(args)
    if type(args) ~= "table" then
        return PageView.new({pageview = args})
    end
    return PageView.new(args);
end

function BaseWnd:clonePrefab(childName)
	if self.prefab then
        local child = self:widget(childName,self.prefab);
		return child:clone();
	end
	return nil;
end


function BaseWnd:setupCloseBtn(path)
	path = path or "close";
	local btn = self:widget(path);
	btn:setTouchEnabled(true);
	local wndName = self.wndData.name;
	btn:onButtonClicked(function()
		mgrs.log:printDebug("closeWndName = %s",wndName);
		mgrs.wnd:closeWnd(wndName);
	end);
end

function BaseWnd:setupClose(path)
    path = path or "close";
	local img = self:widget(path);
    local wndName = self.wndData.name;
    self:createClick({targetNode = img}):clickHandler(function()
        mgrs.log:printDebug("closeWndName = %s",wndName);
		mgrs.wnd:closeWnd(wndName);
    end);
end


return BaseWnd;
